package com.bt.lms.ui.action.school_education.transferin_info;

import com.alibaba.fastjson.JSON;
import com.bt.lms.constants.BOConstant;
import com.bt.lms.constants.StuStatusBizTypeConstant;
import com.bt.lms.entity.TransferInfo;
import com.bt.lms.network.msg.ReqMsg;
import com.bt.lms.network.msg.RespMsg;
import com.bt.lms.ui.page.sys.style.BtnStyle;
import com.bt.lms.ui.vo.school_education.transactionInfo.AddTransactionInfoVo;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Cursor;
import javafx.scene.control.*;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import org.apache.commons.beanutils.BeanUtils;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.Socket;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.Date;

/**
 * 添加学籍异动验证事件
 */
public class AddTransferInfoVerify implements EventHandler {

    private VBox vBox;

    private HBox one;

    public AddTransferInfoVerify(VBox box, HBox one) {
        this.vBox = box;
        this.one = one;
    }

    @Override
    public void handle(Event event) {

        //1.获取用户输入
        AddTransactionInfoVo addTransactionInfoVo = getInput();
        //2.验证用户输入是否合法
        String verifyMsg = getVerifyMsg(addTransactionInfoVo);
        //3.组包
        byte[] bytes = null;
        if (verifyMsg == null) {
            bytes = handle2Msg(addTransactionInfoVo);
        }
        //4.组网
        Socket socket = getNet();
        //5.发送消息
        boolean flag = sendMsg(bytes, socket, addTransactionInfoVo);

    }

    /**
     * 发送消息
     *
     * @param bytes                字节数组
     * @param socket               网
     * @param addTransactionInfoVo vo对象
     * @return 是否成功
     */
    private boolean sendMsg(byte[] bytes, Socket socket, AddTransactionInfoVo addTransactionInfoVo) {
        try {
            OutputStream out = socket.getOutputStream();
            out.write(bytes);
            out.flush();


            //接收响应消息
            InputStream in = socket.getInputStream();
            byte[] buf = new byte[1024];
            in.read(buf);
            RespMsg respMsg = RespMsg.toRespMsg(buf);
            String data = respMsg.getData();
            if (data != null) {
                Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
                alert.setContentText("保存成功");
                alert.showAndWait();
            }
            //界面回显
            VBox vBox1 =initPage(addTransactionInfoVo);



        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        return true;
    }

    /**
     * 界面回显
     * @param addTransactionInfoVo vo对象
     * @return vbox
     */
    private VBox initPage(AddTransactionInfoVo addTransactionInfoVo) {
        VBox vBox1 = new VBox();
        double baseWidth = 1200;
        HBox hBox = new HBox();
        hBox.setPrefWidth(baseWidth-200);
        Insets insets1 = new Insets(0,50,0,10);
        hBox.setPadding(insets1);
        hBox.setAlignment(Pos.CENTER_RIGHT);
        Button editBtn = new Button("💻编辑");
        hBox.getChildren().add(editBtn);
        //按钮样式
        BtnStyle.saveBtn(editBtn);
        editBtn.setCursor(Cursor.HAND);

        //事件
        TransferInfoEditAction transferInfoEditAction = new TransferInfoEditAction(this.vBox,this.one);
        editBtn.setOnAction(transferInfoEditAction);
        vBox1.getChildren().add(hBox);

        HBox hBox1 = new HBox();
        hBox1.setPrefWidth(baseWidth);
        hBox1.setSpacing(10);

        VBox one1 = new VBox();
        one1.setPrefWidth(baseWidth/8);
        one1.setSpacing(10);
        Label variationSortLab = new Label("异动类别");
        Label variationCauseLab = new Label("异动原因");
        Label variationDataLab = new Label("异动日期");
        Label variationStateLab = new Label("异动说明");
        one1.getChildren().addAll(variationSortLab,variationCauseLab,variationDataLab,variationStateLab);
        hBox1.getChildren().add(one1);

        VBox one2 = new VBox();
        one2.setPrefWidth(baseWidth/3);
        one2.setSpacing(10);
        //异动类别
        Integer type = addTransactionInfoVo.getType();
        String leave = "";
        switch (type){
            case 1:
                leave = "停学";
                break;
            case 2:
                leave = "休学";
                break;
            case 3:
                leave = "停复";
                break;
            case 4:
                leave = "修复";
                break;
            case 5:
                leave = "退学";
                break;
            case 6:
                leave = "转专业";
                break;
        }
        Label variationSortLabMes = new Label(leave);
        Label variationCauseLabMes = new Label("停学后复学");
        Label variationDataLabMes = new Label("2012年7月6日");
        Label variationStateLabMes = new Label();
        one2.getChildren().addAll(variationSortLabMes,variationCauseLabMes,variationDataLabMes,variationStateLabMes);
        hBox1.getChildren().add(one2);


        VBox one3 = new VBox();
        one3.setPrefWidth(baseWidth/7);
        one3.setSpacing(10);
        Label variationFrontStateLab = new Label("异动前学籍状态");
        Label variationQueenStateLab = new Label("异动后学籍状态");
        Label Lab = new Label();
        one3.getChildren().addAll(variationFrontStateLab,variationQueenStateLab,Lab);
        hBox1.getChildren().add(one3);

        VBox one4 = new VBox();
        one4.setPrefWidth(baseWidth/3);
        one4.setSpacing(10);
        Label variationFrontStateLabMes = new Label("停学");
        Label variationQueenStateLabMes = new Label("在籍");
        Label approvalDataLabMes = new Label();
        Label labMes = new Label();
        one4.getChildren().addAll(variationFrontStateLabMes,variationQueenStateLabMes,approvalDataLabMes,labMes);
        hBox1.getChildren().add(one4);

        VBox one5 = new VBox();
        one5.setSpacing(10);
        one5.setPrefWidth(baseWidth/3);
        Label choiceLab1 = new Label();
        Label choiceLab2 = new Label();
        Label choiceLab3 = new Label();
        Label choiceLab4 = new Label();
        one5.getChildren().addAll(choiceLab1,choiceLab2,choiceLab3,choiceLab4);
        hBox1.getChildren().add(one5);
        vBox1.getChildren().add(hBox1);

        return vBox1;

    }

    /**
     * 获取网
     *
     * @return 网
     */
    private Socket getNet() {
        Socket socket = null;
        try {
            socket = new Socket("127.0.0.1", 8888);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        return socket;
    }

    /**
     * 根据网络协议组包
     *
     * @param addTransactionInfoVo vo对象
     * @return byte数组
     */
    private byte[] handle2Msg(AddTransactionInfoVo addTransactionInfoVo) {
        ReqMsg reqMsg = new ReqMsg();
        reqMsg.setBizType(StuStatusBizTypeConstant.TRANSACTION_INFO_BIZ_TYPE_ADD);
        reqMsg.setReqId(new Date().getTime());
        TransferInfo transferInfo = new TransferInfo();
        try {
            BeanUtils.copyProperties(transferInfo, addTransactionInfoVo);
            transferInfo.setId(1L);

        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        }
        String transferStr = JSON.toJSONString(transferInfo);
        reqMsg.setData(transferStr);

        return reqMsg.toBytes();

    }

    /**
     * 验证用户输入
     *
     * @param addTransactionInfoVo vo对象
     * @return 验证的消息
     */
    private String getVerifyMsg(AddTransactionInfoVo addTransactionInfoVo) {

        String msg = "";

        if (addTransactionInfoVo.getType() != null) {

        }
        if (addTransactionInfoVo.getBeforeState() != null) {

        }
        if (addTransactionInfoVo.getCause() != null) {
            if (addTransactionInfoVo.getCause().length() > 128) {
                msg += "异动原因在0-128之间\r\n";
            }
        }
        if (addTransactionInfoVo.getLaterState() != null) {

        }
        if (addTransactionInfoVo.getDate() != null) {
            long data = addTransactionInfoVo.getDate().getTime();
            long now = LocalDate.now().atStartOfDay().toInstant(ZoneOffset.of("+8")).toEpochMilli();
            if (data > now) {
                msg += "异动日期必须在当前时间之前\r\n";
            }
        }
        if (addTransactionInfoVo.getExplain() != null) {
            if (addTransactionInfoVo.getExplain().length() > 255) {
                msg += "异动说明在0-255位之间\r\n";
            }
        }

        if (!msg.equals("")) {
            Alert alert = new Alert(Alert.AlertType.WARNING);
            alert.setContentText(msg);
            alert.show();
        }
        if (msg.equals("")) {
            msg = null;
        }

        return msg;

    }

    /**
     * 获取用户输入
     *
     * @return vo对象
     */
    private AddTransactionInfoVo getInput() {

        AddTransactionInfoVo addTransactionInfoVo = new AddTransactionInfoVo();

        ComboBox anomalousClassCB = (ComboBox) this.vBox.lookup("#anomalousClassCB");
        if (anomalousClassCB.getValue() != null) {
            String anomalousClassStr = (String) anomalousClassCB.getValue();
            int leave = -1;
            switch (anomalousClassStr) {
                case "停学":
                    leave = BOConstant.TRANSFER_INFO_TRANSFER_TYPE_STOP_GOING_TO_SCHOOL;
                    break;
                case "休学":
                    leave = BOConstant.TRANSFER_INFO_TRANSFER_TYPE_QUIT_SCHOOL;
                    break;
                case "停复":
                    leave = BOConstant.TRANSFER_INFO_TRANSFER_TYPE_STOP_AND_RESUME;
                    break;
                case "休复":
                    leave = BOConstant.TRANSFER_INFO_TRANSFER_TYPE_REFRACTORY_PERIOD;
                    break;
                case "退学":
                    leave = BOConstant.TRANSFER_INFO_TRANSFER_TYPE_DROP_OUT;
                    break;
                case "转专业":
                    leave = BOConstant.TRANSFER_INFO_TRANSFER_TYPE_SWITCH_MAJOR;
                    break;
            }
            addTransactionInfoVo.setType(leave);
        }


        ComboBox oldChangeStatusTF = (ComboBox) this.vBox.lookup("#oldChangeStatusTF");
        if (oldChangeStatusTF.getValue() != null) {
            String value = (String) oldChangeStatusTF.getValue();
            int leave = -1;
            switch (value) {
                case "在籍":
                    leave = BOConstant.TRANSFER_INFO_BEFORE_STATE_ON_THE_REGISTER;
                    break;
                case "未注册":
                    leave = BOConstant.TRANSFER_INFO_BEFORE_STATE_UNREGISTERED;
                    break;
                case "休学":
                    leave = BOConstant.TRANSFER_INFO_BEFORE_STATE_QUIT_SCHOOL;
                    break;
                case "退学":
                    leave = BOConstant.TRANSFER_INFO_BEFORE_STATE_DROP_OUT;
                    break;
                case "开除":
                    leave = BOConstant.TRANSFER_INFO_BEFORE_STATE_EXPEL;
                    break;
                case "毕业":
                    leave = BOConstant.TRANSFER_INFO_BEFORE_STATE_GRADUATE;
                    break;
                case "异动中":
                    leave = BOConstant.TRANSFER_INFO_BEFORE_STATE_ALTERNATION;
                    break;
            }
            addTransactionInfoVo.setBeforeState(leave);
        }

        TextField changeReasonTF = (TextField) this.vBox.lookup("#changeReasonTF");
        String changeReasonTFStr = changeReasonTF.getText().trim();
        addTransactionInfoVo.setCause(changeReasonTFStr);

        ComboBox newChangeStatusCB = (ComboBox) this.vBox.lookup("#newChangeStatusCB");
        if (newChangeStatusCB.getValue() != null) {
            String value = (String) newChangeStatusCB.getValue();
            int leave = -1;
            switch (value) {
                case "在籍":
                    leave = BOConstant.TRANSFER_INFO_LATER_STATE_ON_THE_REGISTER;
                    break;
                case "未注册":
                    leave = BOConstant.TRANSFER_INFO_LATER_STATE_UNREGISTERED;
                    break;
                case "休学":
                    leave = BOConstant.TRANSFER_INFO_LATER_STATE_QUIT_SCHOOL;
                    break;
                case "退学":
                    leave = BOConstant.TRANSFER_INFO_LATER_STATE_DROP_OUT;
                    break;
                case "开除":
                    leave = BOConstant.TRANSFER_INFO_LATER_STATE_EXPEL;
                    break;
                case "毕业":
                    leave = BOConstant.TRANSFER_INFO_LATER_STATE_GRADUATE;
                    break;
                case "异动中":
                    leave = BOConstant.TRANSFER_INFO_LATER_STATE_ALTERNATION;
                    break;
            }
            addTransactionInfoVo.setLaterState(leave);
        }
        DatePicker changeDateDP = (DatePicker) this.vBox.lookup("#changeDateDP");
        if (changeDateDP.getValue() != null) {
            LocalDate value = changeDateDP.getValue();
            Instant instant = value.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant();
            Date from = Date.from(instant);
            addTransactionInfoVo.setDate(from);
        }


        TextArea explainAR = (TextArea) this.vBox.lookup("#explainAR");
        String explainARStr = explainAR.getText().trim();
        addTransactionInfoVo.setExplain(explainARStr);


        return addTransactionInfoVo;
    }
}
